// $codepro.audit.disable numericLiterals
/**
 * package for all the model classes to fit the mvc format
 */
package javamonsters.model;

import java.awt.Point;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * The SolarSystem class represents a solar system inside a
 * universe, knowing details such as its name,
 * location, tech level, and attributes.
 * 
 * @author wa
 * @version 1.0
 */
public class SolarSystem implements java.io.Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 6231478245069572915L;
	
	/**
	 * object output stream
	 */
	private ObjectOutputStream out;

	/**
	 * The name.
	 */
	private final String name;
	
	/**
	 * The position in the universe.
	 */
	private final Point coordinates;
	
	/**
	 * The tech level.
	 */
	private final TechLevels techLevel;
	
	/**
	 * The attributes.
	 */
	private final Attributes attributes;
	
	/**
	 * The planets contained in the solar system.
	 */
	private final List<Planet> planets = new ArrayList<Planet>(1);
	
	/**
	 * The Enum TechLevels represents the possible tech levels a solar system can have.
	 */
	public enum TechLevels {
		
		/**
		 * The pre agriculture.
		 */
		PRE_AGRICULTURE { 
			public String toString() { 
				return "Pre-Agriculture"; 
			}
		},
		
		/**
		 * The agriculture.
		 */
		AGRICULTURE { 
			public String toString() { 
				return "Agriculture";
			}
		},
		
		/**
		 * The medieval.
		 */
		MEDIEVAL { 
			public String toString() {
				return "Medieval"; 
			}
		},
		
		/**
		 * The renaissance.
		 */
		RENAISSANCE { 
			public String toString() {
				return "Renaissance"; 
			}
		},
		
		/**
		 * The early industrial.
		 */
		EARLY_INDUSTRIAL {
			public String toString() {
				return "Early Industrial";
			}
		},
		
		/**
		 * The industrial.
		 */
		INDUSTRIAL { 
			public String toString() { 
				return "Industrial";
			}
		},
		
		/**
		 * The post industrial.
		 */
		POST_INDUSTRIAL {
			public String toString() { 
				return "Post-Industrial"; 
			}
		},
		
		/**
		 * The hi tech.
		 */
		HI_TECH { 
			public String toString() {
				return "Hi-Tech";
			}
		};
		
		/**
		 * Chooses a random tech level.
		 *
		 * @return the tech level
		 */
		public static TechLevels chooseTechLevel() {
			final Random rand = new Random();
			return TechLevels.values()[rand.nextInt(TechLevels.values().length)];
		}
		
	};
	
	/**
	 * The Enum Attributes represents the possible attributes a solar system can have.
	 */
	/**
	 * @author Evan
	 *
	 */
	public enum Attributes {
		
		/**
		 * The no special resources.
		 */
		NO_SPECIAL_ATTRIBUTE { 
			public String toString() {
				return "No Special Attribute";
			}
		},
		
		/**
		 * The mineral rich.
		 */
		MINERAL_RICH { 
			public String toString() { 
				return "Mineral-Rich";
			}
		},
		
		/**
		 * The mineral poor.
		 */
		MINERAL_POOR {
			public String toString() {
				return "Mineral-Poor";
			}
		},
		
		/**
		 * The desert.
		 */
		DESERT { 
			public String toString() { 
				return "Desert-Ridden"; 
			}
		},
		
		/**
		 * The lots of water.
		 */
		LOTS_OF_WATER {
			public String toString() { 
				return "Water-Abundant";
			}
		},
		
		/**
		 * The rich soil.
		 */
		RICH_SOIL { 
			public String toString() {
				return "Rich Soil";
			}
		},
		
		/**
		 * The poor soil.
		 */
		POOR_SOIL {
			public String toString() {
				return "Poor Soil";
			}
		},
		
		/**
		 * The rich fauna.
		 */
		RICH_FAUNA { 
			public String toString() {
				return "Rich Fauna";
			}
		},
		
		/**
		 * The lifeless.
		 */
		LIFELESS {
			public String toString() {
				return "Lifeless";
			}
		},
		
		/**
		 * The weird mushrooms.
		 */
		WEIRD_MUSHROOMS {
			public String toString() { 
				return "Weird Mushrooms";
			}
		},
		
		/**
		 * The lots of herbs.
		 */
		LOTS_OF_HERBS {
			public String toString() {
				return "Herb-Filled"; 
			}
		},
		
		/**
		 * The artistic.
		 */
		ARTISTIC {
			public String toString() {
				return "Artistic";
			}
		},
		
		/**
		 * The warlike.
		 */
		WARLIKE { 
			public String toString() {
				return "Warlike"; 
			}
		},
		
		/**
		 * Place-holder for goods that have no cheap or expensive conditions
		 */
		NOTHING;
		
		/**
		 * Chooses a semi-random attribute weighted towards NO_SPECIAL_RESOURCES.
		 *
		 * @return the attribute
		 */
		public static Attributes chooseAttribute() {
			if (Math.random() > .5) {
				final Random rand = new Random();
				//Makes it so that SolarSystem will never have the NOTHING attribute...only Trade Goods can have it
				Attributes attribute = Attributes.NOTHING;
				while (attribute == Attributes.NOTHING) {
					attribute = Attributes.values()[1 + rand.nextInt(
							Attributes.values().length - 1)];
				}
				return attribute;
			} else {
				return Attributes.NO_SPECIAL_ATTRIBUTE;
			}
		}
		
	}
	
	/**
	 * Constructor that takes in and instantiates the solar system's details.
	 *
	 * @param name the name
	 * @param coordinates the position
	 * @param techLevel the tech level
	 * @param attributes the attributes
	 */
	public SolarSystem(String name, Point coordinates, TechLevels techLevel,
		   Attributes attributes) {
		/*
		 * Should this have to pass Character throughout the whole program?
		 */
		
		this.name = name;
		this.coordinates = coordinates;
		this.techLevel = techLevel;
		this.attributes = attributes;
		
		this.planets.add(new Planet(this, name));
	}
	
	/**
	 * Getter that returns the solar system's name.
	 *
	 * @return name
	 */
	public String getName() {
		return this.name;
	}
	
	/**
	 * Getter that returns the solar system's X and Y coordinates.
	 *
	 * @return coordinates
	 */
	public Point getCoordinates() {
		return this.coordinates;
	}
	
	/**
	 * Getter that returns the solar system's tech level.
	 *
	 * @return techLevel
	 */
	public TechLevels getTechLevel() {
		return this.techLevel;
	}
	
	/**
	 * Getter that returns the solar system's attributes.
	 *
	 * @return attributes
	 */
	public Attributes getAttributes() {
		return this.attributes;
	}
	
	/**
	 * getter for the SolarSystem's Planets
	 * 
	 * @return an ArrayList of the Planets in the SolarSystem
	 */
	public List<Planet> getPlanets() {
		return planets;
	}
	
	/**
	 * writes this object to a save file
	 * 
	 * @param filename the name of the file to be written to
	 * @throws IOException
	 */
	public void writeObject(String filename) throws IOException {
		try {
			out = new ObjectOutputStream(new FileOutputStream(filename + ".dat"));
			out.writeObject(this);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			out.close();
		}
	}

	/**
	 * @return String representation of solar system
	 */
	public String toString() {
		return "solar system";
	}
}
